#include "stdafx.h"
#include "DiamondSquare.h"

#include "../../../Framework/Toolkit.h"

using namespace Framework;

namespace MyGame {

DiamondSquare::DiamondSquare(void) {
    this->displacement = 0.0f;
    this->midpointDisplacement = 0.05f;
}

DiamondSquare::~DiamondSquare(void) {
}

FLOAT DiamondSquare::GetDisplacement() const {
    return this->displacement;
}
void DiamondSquare::SetDisplacement(FLOAT val) {
    this->displacement = val;
}
FLOAT DiamondSquare::GetMidpointDisplacement() const {
    return this->midpointDisplacement;
}
void DiamondSquare::SetMidpointDisplacement(FLOAT val) {
    this->midpointDisplacement = val;
}

void DiamondSquare::Generate(HeightMap* heightMap) {
    this->map = heightMap->GetMap();
    int width = heightMap->GetWidth();
    int length = heightMap->GetLength();

    if (heightMap->GetMaxElevation() == 0.0f) {
        map[0][0] = 0.5f;
        map[width - 1][0] = 0.5f;
        map[0][length - 1] = 0.5f;
        map[width - 1][length - 1] = 0.5f;
    }

    this->Generate(0, 0, width - 1, length - 1);
    this->map = NULL;
}

void DiamondSquare::Generate(int x1, int y1, int x2, int y2) {
    int xs = x1 + (x2 - x1) / 2;
    int ys = y1 + (y2 - y1) / 2;
    this->map[xs][y1]=(this->map[x1][y1] + this->map[x2][y1]) / 2 + (FLOAT)(Toolkit::RandomFloat(x1, x2) - Toolkit::RandomFloat(x1, x2)) * this->displacement;
    this->map[x2][ys]=(this->map[x2][y1] + this->map[x2][y2]) / 2 + (FLOAT)(Toolkit::RandomFloat(x1, x2) - Toolkit::RandomFloat(x1, x2)) * this->displacement;
    this->map[xs][y2]=(this->map[x1][y2] + this->map[x2][y2]) / 2 + (FLOAT)(Toolkit::RandomFloat(x1, x2) - Toolkit::RandomFloat(x1, x2)) * this->displacement;
    this->map[x1][ys]=(this->map[x1][y1] + this->map[x1][y2]) / 2 + (FLOAT)(Toolkit::RandomFloat(x1, x2) - Toolkit::RandomFloat(x1, x2)) * this->displacement;
    this->map[xs][ys]=(this->map[x1][y1] + this->map[x2][y1] + this->map[x2][y2] + this->map[x1][y2]) / 4 + (FLOAT)(Toolkit::RandomFloat(x1, x2) - Toolkit::RandomFloat(x1, x2)) * this->midpointDisplacement;

    if ((xs > x1) && (ys > y1)) {
        this->Generate(x1, y1, xs, ys);
        this->Generate(xs, y1, x2, ys);
        this->Generate(xs, ys, x2, y2);
        this->Generate(x1, ys, xs, y2);
    }
}

}
